package com.sky.service.impl;

import com.sky.entity.Orders;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.UserMapper;
import com.sky.service.ReportService;
import com.sky.vo.OrderReportVO;
import com.sky.vo.TurnoverReportVO;
import com.sky.vo.UserReportVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class ReportServiceImpl implements ReportService {
	
	private final OrderMapper orderMapper;
	
	private final UserMapper userMapper;
	
	public ReportServiceImpl(OrderMapper orderMapper, UserMapper userMapper) {
		this.orderMapper = orderMapper;
		this.userMapper = userMapper;
	}
	
	@Override
	public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {
		List<LocalDate> dateList = getDateList(begin, end);
		List<Double> turnovers = new ArrayList<>();
		dateList.forEach(date -> {
			Map<String, Object> map = new HashMap<>();
			map.put("status", Orders.COMPLETED);
			map.put("begin", LocalDateTime.of(date, LocalTime.MIN));
			map.put("end", LocalDateTime.of(date, LocalTime.MAX));
			Double turnover = orderMapper.completedOrder(map);
			turnovers.add(turnover == null ? 0 : turnover);
		});
		return new TurnoverReportVO(StringUtils.join(dateList, ","), StringUtils.join(turnovers, ","));
	}
	
	@Override
	public UserReportVO userStatistics(LocalDate begin, LocalDate end) {
		//1.获取时间区间内的每一天的时间
		//1.1 定义一个list用来封装每一天的时间
		List<LocalDate> dateList = getDateList(begin, end);
		//2.5 定义两个list用来封装每天的新增用户数量和总用户量
		List<Integer> newUserCountList = new ArrayList<>();
		List<Integer> totalUserCountList = new ArrayList<>();
		//2.查询mysql,查询每一天的新增用户和总用户量
		for (LocalDate date : dateList) {
			//2.1.获取当天的最小时间，年月日时分秒 00:00
			LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
			//2.2 获取当天的最大时间，年月日时分秒 59:59
			LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
			
			Map map = new HashMap();
			//2.3 查询mysql 获取当天的总用户数量 select count(id) from user where  create_time<#{end}
			map.put("end", endTime);
			Integer totalUserCount = userMapper.getUserCount(map);
			//2.4查询mysql获取当天的新增用户数量  select count(id) from user where create_time>#{begin} and create_time<#{end}
			map.put("begin", beginTime);
			Integer newUserCount = userMapper.getUserCount(map);
			//2.6 插入数据到list中
			newUserCountList.add(newUserCount);
			totalUserCountList.add(totalUserCount);
		}
		//3.返回数据
		return UserReportVO.builder()
				.dateList(StringUtils.join(dateList, ","))
				.newUserList(StringUtils.join(newUserCountList, ","))
				.totalUserList(StringUtils.join(totalUserCountList, ","))
				.build();
	}
	
	@Override
	public OrderReportVO orderStatistics(LocalDate begin, LocalDate end) {
		List<LocalDate> dateList = getDateList(begin, end);
		List<Integer> orderCountList = new ArrayList<>();
		List<Integer> validOrderCountList = new ArrayList<>();
		dateList.forEach(date -> {
			Map<String, Object> map = new HashMap<>();
			map.put("begin", LocalDateTime.of(date, LocalTime.MIN));
			map.put("end", LocalDateTime.of(date, LocalTime.MAX));
			Integer totalOrder = orderMapper.orderCount(map);
			orderCountList.add(totalOrder == null ? 0 : totalOrder);
			map.put("status", Orders.COMPLETED);
			Integer validOrder = orderMapper.orderCount(map);
			validOrderCountList.add(validOrder == null ? 0 : validOrder);
		});
		Integer totalOrderCount = orderCountList.stream().reduce(Integer::sum).get();
		Integer validOrderCount = validOrderCountList.stream().reduce(Integer::sum).get();
		Double orderCompletionRate = 0.0;
		if (totalOrderCount != 0) {
			orderCompletionRate = validOrderCount.doubleValue() / totalOrderCount;
		}
		return OrderReportVO.builder()
				.dateList(StringUtils.join(dateList, ","))
				.orderCompletionRate(orderCompletionRate)
				.validOrderCount(validOrderCount)
				.totalOrderCount(totalOrderCount)
				.orderCountList(StringUtils.join(orderCountList, ","))
				.validOrderCountList(StringUtils.join(validOrderCountList, ","))
				.build();
		
	}
	
	private List<LocalDate> getDateList(LocalDate begin, LocalDate end) {
		List<LocalDate> dateList = new ArrayList<>();
		while (!begin.isAfter(end)) {
			dateList.add(begin);
			begin = begin.plusDays(1);
		}
		return dateList;
	}
}
